Translated by visionNoob, KNU https://github.com/insurgent92/CS231N_17_KOR_SUB
시작하겠습니다!
안녕하세요 저를 처음 보시는분들도 계실텐데요
제 이름은 Serena Yeung이고 이 강의의 세 번째이자 마지막 강사입니다
또한 Fei-Fei 교수님 그룹에서 박사 과정 학생입니다
오늘 우리는 backpropagation과 neural network에 대해 이야기하려 합니다
우리는 이제부터 이 수업의 핵심이 되는 것을 얻을 것입니다
시작하기전에 음...
몇 가지 확인할 사항이 있습니다
[과제 1]이 4월 20일 목요일까지입니다.
다시 말씀드리지만, 우리는 마감일을 조금 뒤로 늦췄습니다
당일 오후 11시59분까지 Canvas에 제출되어야 합니다
그러므로 당신은 당신의 프로젝트에 대해 신경써야할 것입니다
Piazza에 전공 TA 리스트가 있습니다
프로젝트 주제에 대해 궁금한 것이 생기면 관련된 TA들을 찾아보는 것을 고려할 수 있습니다
그리고 Google Cloud 사용을 위한 100$를 받게 될 것입니다
과제 및 프로젝트를 위한 것이며 당신은 이번주에 관련 email을 받을 것입니다
많은 분들이 이미 가지고 있을 수 있지만 없는 사람들을 위해 이번 주말까지 전송될 것입니다
자, 우리는 어떻게 classifier를 정의하는지 함수 f를 통해 이야기 했었습니다
weights W를 파라미터로 가지고 있고, 이 함수 f는 데이터 x가 입력(input)이고
출력(output)은 분류하고자 하는 클래스들에 대한 score vector 입니다
또한 우리는 loss function을 정의할 수 있습니다 SVM loss function을 예로 들면
우리가 행복한지 불행한지를 점수로 나타내 이야기 할 때 우리는 total loss 항(term)을 정의해 사용할 수 있습니다
여기서 loss function은 데이터 항의 조합으로 이루어져 있는데 정규화 항을 포함하고 있습니다
정규화 항은 얼마나 우리의 모델이 단순한지 더 나은 일반화를 위해 적합한 단순 모델을 가지고 있는지를 표현해줍니다
또한 우리는 최적의 loss를 갖게 하는 파라미터 W를 찾고 싶습니다
그래서 우리는 loss function의 W에 관한 gradient를 찾았습니다
이전 강의에서 어떻게 optimization을 사용해서 구할 수 있는지 이야기 했습니다.
gradient가 음수인 방향, 즉 경사가 하강하는 방향을 반복적으로 구해 아래로 나아갈 수 있고, 우리는 가장 낮은 loss에 찾게 될 것입니다.
그리고 우리는 경사 하강법(gradient descent)이 오른쪽 이미지와 같이 기본적으로 이런 궤도를 나타내는 것을 보았습니다.
오!
우리는 또한 gradient를 구하는 다른 방법에 대해서도 이야기했습니다.
우리는 수학적으로 유한 차분 근사(finite differnce approximation)를 이용해 계산할 수 있습니다.
비록 이것은 느리고 또한 근사치이지만 써내려가면서 하기에 가장 쉬운 방법입니다.
당신은 언제나 이 방법을 이용해 gradient를 얻을 수 있다는 것을 알고 있습니다.
analytic gradient를 어떻게 사용하지 그리고 계산하는 것까지 이야기했습니다.
analytic gradient를 사용하는 것은 빠르고 정확합니다.
하지만 당신은 이 식을 유도하기 위해 많은 수학과 함께 미적분학을 해야 합니다. 또한 실수하기 쉽다는 것을 알아두세요.
실제로 우리가 원하는것은 analytic gradient를 유도하고 사용하는 것입니다.
하지만 동시에 analytic gradient를 사용한 응용에 대해서 수학적 검증이 필요합니다.
그래서 오늘은 임의의 복잡한 함수를 통해 어떻게 analytic gradient를 계산하는지에 대해 이야기할 것입니다.
computational graph라고 부르는 프레임워크를 사용할 것입니다.
그리고 기본적으로 computational graph 같은 종류의 그래프를 이용해서 어떤 함수든지 표현할 수 있습니다.
그리고 그래프의 각 노드는 연산 단계를 나타냅니다.
예를들면 이 예제는 우리가 말해왔던 input이 x,W인 선형 classifier입니다.
곱셈 노드는 행렬 곱셈을 나타냅니다. 파라미터 W와 데이터 x의 곱셈은 score vector를 출력합니다.
그리고 우리는 hinge loss라는 다른 계산 노드를 가지고 있습니다.
데이터 항 Lᵢ를 계산하는데, 우리는 오른쪽 하단에 보이 regularization 항 또한 가지고 있습니다.
이 노드(R)는 regularization 항을 계산하고 우리의 최종 loss는 L은 regularization 항과 데이터 항의 합입니다.
computational graph를 사용해서 함수를 표현하게 됨으로써 backpropagation이라고 부르는 기술을 사용할 수 있게 됩니다.
backpropagation은 gradient를 얻기위해 computational graph 내부의 모든 변수에 대해 chain rule을 재귀적으로 사용합니다.
그리고 우리는 이것이 어떻게 동작하는지 볼 것입니다.
이것은 우리가 매우 복잡한 함수를 이용하여 작업할때 아주 유용하게 사용됩니다.
예를들면 우리가 이 수업에서 이야기하게 될 CNN은 가장 윗층(top)에 입력 이미지가 들어가고 아래(bottom)에는 loss가 있습니다.
입력 이미지는 loss function으로 가기까지 많은 layer를 거쳐 변형을 겪게 됩니다.
이것은 심지어 상상하는만큼 미칠(crazier) 수 있습니다.
여러분은 딥러닝의 다른 종류인 neural turing machine을 알고있을텐데요 이 경우의 computational graph를 볼 수 있습니다.
이것은 아주 미쳤지만 특별합니다. 우리는 결국 시간이 지남에 따라 이것을 풀게 될 것입니다.
만약 여러분이 어떤 중간 변수의 gradient를 계산하고 싶으면 이것은 기본적으로 아주 비실용적입니다.
자 어떻게 backpropagation이 동작할까요? 간단한 예제부터 시작해봅시다.
일단, 우리의 목표는 우리가 함수를 가지는 것입니다.
이 경우 x,y,z로 구성된 function f는 (x+y)*z와 같습니다.
그리고 우리는 function f의 출력에 대한 어떤 변수의 gradient를 찾기 원합니다.
그래서 첫 번째 단계는 항상 함수 f를 이용해서 computational graph로 나타내는 것입니다.
computational graph가 오른쪽에 있습니다.
x,y에 대한 덧셈 노드를 보실 수 있으며 오른쪽에는 다음 연산을 위한 곱셈 노드도 가지고 있습니다.
그리고 이 네트워크에 우리가 가지고 있는 값을 전달할 것입니다.
x는 -2, y는 5, z는 -4입니다.
또한 중간중간 값도 계산하여 computational graph에 값을 적어 놓았습니다.
x+y는 3입니다. 그리고 마지막으로 최종 노드를 통과시켜 -12를 얻습니다.
여기에서 모든 중간 변수에 이름을 줘봅시다.
그래서 나는 x+y 덧셈 노드를 q라고 부를 것입니다.
또한 여기에서 f는 q*z입니다.
그리고 저는 x와 y에 각각에 대한 q의 gradient를 표시해 놓았습니다. 그것은 단순 덧셈이기때문에 1입니다.
그리고 q와 z에 대한 f의 gradient는 곱셈규칙에 의해 각각 z와 q입니다.
그리고 우리가 찾기 원하는것은 x,y,z 각각에 대한 f의 gradient입니다.
backpropagation은 chain rule의 재귀적인 응용입니다. chiain rule에 의해 우리는 뒤에서부터 시작합니다.
computational graph의 가장 끝, 우리는 뒤에서부터 gradient를 계산합니다.
끝에서부터 시작해봅시다. 우리는 출력의 f에 대한 gradient를 계산하길 원합니다.
그리고 이 gradient는 1입니다, 쉽죠.
이번에는 뒤로 이동해서 z에 대한 gradient를 계산해봅시다. 여러분은 z에 대한 f의 미분이 q라는 것을 알고 있습니다.
그리고 q의 값은 3이죠. 그래서 여기에서 z에 대한 f의 미분값은 3을 갖습니다.
그리고 다음으로 q에 대한 f의 미분값을 알아봅시다. 값이 얼마일까요?
q에 대한 f의 미분값은 얼마인가요?
q에 대한 f의 미분값은 z와 같네요.
그리고 z는 여기에서 -4입니다. 여기에서 우리는 q에 대한 f의 미분값이 -4라는 것을 알았습니다.
자 이제 그래프의 뒤로 이동해봅시다. 여러분은 y에 대한 f의 미분값을 알고 싶습니다.
하지만 여기에서 y는 f와 바로 연결되어 있지 않습니다.
f는 z와 연결되어있습니다. 이것을 구하는 방법은 chain rule을 이용합니다.
y에 대한 f의 미분은 q에 대한 f의 미분과 y에 대한 q의 미분의 곱으로 나타낼 수 있습니다.
이것은 직관적으로 y가 f에 미치는 영향을 구하기 위한 것을 알수 있죠.
실제로 이것은 우리가 q*f의 연산에서 q의 영향을 구할때와 동등합니다.
q에 대한 f의 미분은 -4이고, q에 대한 y의 영향력 즉 y에 대한 q의 미분과 합성(곱)합니다.
이 예제에서 y에 대한 q의 미분은 얼마인가요?
[학생] 1
맞아요. 정확합니다.
y에 대한 q의 미분은 1이죠, 아시다시피.
만약 우리가 y를 조금 변화시키면 q는 그것의 영향력 만큼 조금 변할것입니다.
그리고 이것은 내가 y를 조금 바꿨을때 그것이 q에 대해 1만큼의 영향력을 미치는 것을 의미합니다.
그리고 f에 대한 q의 영향력은 정확하게 -4의 입니다.
이것들을 곱해보면 우리는 f에 대한 y의 영향력으로 -4를 얻습니다. (1 곱하기 -4 이므로)
만약 우리가 똑같이 x의 gradient를 알고싶다고 해봅시다. 여러분은 이전과 같은 방법으로 구할 수 있습니다. 어떻게 할 수 있을까요?
[학생이 마이크로 대답하고 있다]
들었습니다.
정확합니다, 이 경우 우리는 다시한번 chain rule을 적용할 수 있습니다.
우리는 f에 대한 q의 영향력이 -4인것을 알죠
그리고 다시 우리는 같은 덧셈 노드를 가지고 있기 때문에 x에 대한 q의 영향력은 다시한번 1입니다.
f에 대한 x의 gradient는 -4 * 1 이므로 -4입니다.
지금 우리가 하고 있는 backpropagation에서 우리는 computational graph안에 모든 노드를 포함하고 있었습니다.
하지만 각 노드는 오직 주변에 대해서만 알고 있습니다. 그렇죠?
우리가 가지고 있는건 각 노드와 각 노드의 local 입력입니다.
입력은 그 노드와 연결되어있고 값은 노드로 흘러들어가 이 노드로부터 출력을 얻게 됩니다.
여기에서 local 입력은 x,y이고 출력은 z입니다.
그리고 이 노드에서 우리는 local gradient를 구할 수 있습니다. 그렇죠?
우리는 z에서 x에 대한 gradient를 구할 수 있으며 y에 대한 gradient도 마찬가지입니다.
그리고 이것들은 대부분 간단한 연산입니다. 그렇죠?
각 노드는 우리가 이전에 보았던 것처럼 덧셈 혹은 곱셈입니다.
그것들은 쉽게 gradient를 구할 수 있고, 우리는 그것을 찾기 위해 복잡한 미적분을 할 필요가 없습니다.
[학생] 이전으로 돌아가서 설명해 주실수 있으십니까? 어떻게 마지막 슬라이드에서 이 기본적인 미적분으로 넘어왔는지..
네, 다시 돌아가보죠
잠시만요..
여기로 돌아와보면 우리는 미적분학만을 사용해 모든 것을 쓸 수 있습니다.
아시다시피 우리는 x에 대한 f의 미분을 알고 싶었고 우리는 이 식을 사용해서 표현했습니다.
그리고 보시면 이것은 z입니다. 이것은 단순합니다 하지만 정말로 복잡한 표현을 보게 된다면
당신은 무언가의 gradient를 유도하기위해 미적분을 쓰기 싫을 것입니다.
대신 만약 당신이 이 식을 사용하게 되면
당신은 계산 노드를 나눌 수 있으며 이는 gradient를 구하기 위해 아주 단순한 계산만을 사용합니다.
알다시피 덧셈, 곱셈, 지수 같은 것들은 원하는 만큼 단순하고 이 모든 것들을 곱하기 위해 chain rule만 있으면 됩니다.
그러면 gradient를 구할 수 있습니다. 필요한 다른 식은 없습니다.
이해가 되셨나요?
[학생: 웅성웅성]
나중에 이것에 대한 예제를 보겠습니다.
또 다른 질문이 있었습니까?
[학생이 마이크로 말하고 있다]
[학생] z가 나타내는 -4는 무엇입니까?
음.. 네 -4는
위의 초록색 값은 function을 통해 전달되는 값입니다. 그렇죠?
여기에서 x는 -2, y는 5이고, z는 -4입니다.
그리고 우리가 원하는 계산된 다른 값들을 채웠습니다.
우리는 q를 x+y라고 할 수 있습니다. 이것은 -2 + 5이기 때문에 3이 될 것이고 z는 -4죠
최종 값 f는 z와 q를 곱해서 얻을 수 있고 그것은 -4 * 3입니다. 그렇죠?
그리고 아래에 있는 붉은색 값은 gradient에 대해서 적어놓은 것입니다. 우리가 뒤에서부터 계산한.
그래요 우리가 말했던 것처럼 우리가 가지고 있는 각 노드는 local 입력을 받고
보이는 것처럼 다음 노드로 출력값을 보냅니다. 그리고 우리가 계산한 local gradient가 있는데
이는 들어오는 입력에 대한 출력의 기울기입니다.
backpropagation이 어떻게 동작하는지 알아봅시다.
우리는 그래프의 뒤에서 부터 시작합니다.
뒤에서부터 시작 부분까지 끝까지 진행됩니다.
각 노드에 도달하면 출력과 관련한 노드의 gradient가 상류의(입력과 가까운) 노드로 전파됩니다.
그래서 우리는 backpropagation에서 이 노드에 도달할 때까지 z에 대한 최종 loss L은 이미 계산되어있습니다. 그렇죠?
이제 우리는 x와 y의 값에 대한 바로 직전 노드의 gradient를 찾고자합니다.
그리고 우리가 이미 보았듯이, 우리는 chain rule을 사용합니다.
x의 gradient는 z에 대한 gradient와, x에 대한 z의 local gradient로 합성됩니다.
그렇습니다. chain rule에서는 항상 위쪽으로 gradient가 전파됩니다.
그리고 이것(gradient)을 local gradient와 곱해서 (노드의)입력에 대한 gradient를 구합니다.
[학생] 죄송하지만 이 방법은 gradient를 구하는 상징적인 예시일 뿐이지 실제 gradient를 계산하는 일반적인 수식이 아닌것 같습니다.
[학생] 이 방법은 그때그때의 값에 따라서만 동작합니다. 콜록콜록, 또는 약간의 상수 값과 함께요.
질문은 이 방법이 현재 값의 여부와 관계없이 동작하는지에 관한 것이죠?
우리가 연결했던 함수에 현재 값이 주어지면 우리는 이것에 대해 변수에 관한 식으로 나타낼 수 있습니다. 그렇죠?
z에 대한 L의 gradient를 보면 이것은 식으로 나타나 있고,
x에 관한 z의 gradient를 보면 이것은 또 다른 수식입니다 그렇죠? 우리가 이것들에 값을 대입하여 x에 대한 gradient를 얻습니다.
당신이 할 수 있는 것은 이 모든 식을 재귀적으로 사용할 수 있다는 것입니다. 맞죠?
z에 대한 gradient, 그리고 x에 대한 gradient 이것들은 단순한 수식으로 나타납니다.
만약 우리가 곱셈 노드를 가지고 있다고 가정하면 이 경우 x에 대한 z의 gradient는 y가 될 것입니다.
하지만 z에 대한 L의 gradient는 이 그래프 내에서 아주 복잡한 부분입니다.
그렇기 때문에 여기에서 우리는 이 숫자들만 가지고 합니다.
학생이 말했던 것처럼, 이것은 값이 전달되는 기본적인 부분입니다. 우리는 그것을 수식에 따라 곱하고 local gradient를 갖습니다.
나는 이 방식이 더 몇몇 슬라이드의 복잡한 예제보다 명확하다고 생각합니다.
그래서 지금 y에 대한 L의 gradient는 다시 한번 완전히 같은 방식입니다.
chain rule을 사용해서, z에 대한 L의 gradient와 그리고 y에 대한 z의 gradient를 서로 곱합니다. chain rule에 의해 이 둘의 곱은 원하는 gradient를 줍니다.
그리고 나서 우리가 gradient를 구하면 이 노드와 연결된 직전 노드로 전달할 수 있습니다.
이것으로부터 얻을 수 있는 중요한 것은 각 노드는 우리가 계산한 local gradient를 가지고 있습니다.
우리는 backpropagation을 통해 그것을 얻습니다. 값들은 상위 노드 방향으로 계속 전달되고
우리는 이것을 받아 local gradient와 곱하기만 하면 됩니다.
우리는 노드와 연결된 노드 이외의 다른 어떤 값에 대하여 신경쓰지 않아도 됩니다.
이제부터는 다른 예제에 대해서 살펴보겠습니다. 이것은 이전보다는 조금 복잡합니다.
그렇기 때문에 backpropagation이 얼마나 유용한 방식인지를 알게 될 것입니다.
이 경우 함수 w,x에 대한 함수 f는 1 / e^ - (w0x0 + w1x1 + w2)와 같습니다.
다시 말하지만 첫 번째 과정은 이것을 computational graph로 나타내는 것입니다.
이 경우의 graph를 볼 수 있습니다. 먼저 우리는 w와 x를 곱합니다. x0과 x0, x1과 x1 그리고
w2와는 이것들을 모두 더하게됩니다. 그렇죠?
그리고 이것에 -1을 곱하고 exponential을 취하고, 1을 더합니다. 마지막으로 모든 term을 역수로 뒤집습니다. (1/x)
여기서도 값을 채워 놓았습니다.
우리에게 ws와 xs가 주어졌다고 했을때, 우리는 값을 이용해 모든 단계마다 계산을 통해서 앞으로(오른쪽 방향으로) 진행할 수 있습니다.
그리고 아래에다가 나중에 도움이 될 몇몇 유도식을 적어놓았습니다.
이전에 단순한 예제에서 했던 것과 같이
backpropagation을 진행할 것입니다.
다시한번 그래프의 뒤에서부터 시작합니다.
그리고 여기에서 최종 변수에 대한 출력의 gradient는 1입니다.
이제 뒤로 한 스텝 가봅시다. 1/x 이전의 input에 대한 gradient는 얼마입니까?
음.. 이 경우 우리는 upstream gradient를 알고 있습니다. 빨간색으로 쓰여있는 1입니다. 그렇죠?
이것은 흐름에 따라 전파되는 gradient입니다. 이제 local gradient를 찾아야 합니다. 이 노드(1/x)에 대한 local gradient입니다.
우리가 가지고 있는 f는 1/x 이고, 이것의 local gradient인 x에 대한 f의 미분은 -1/x^2와 같습니다. (빨간 박스 참고)
그래서 여기에서 우리는 -1/x^2를 얻습니다. 그리고 x에 값을 대입합니다.
이것(x)은 1.37이고,이 변수에 대한 우리의 최종 gradient는 1/-1.37^2 * 1 = -0.53과 같습니다.
다음 노드로 다시 이동해봅시다.
우리는 똑같은 과정을 거치게 될 것입니다, 맞습니까?
여기에서 upstream gradient는 -0.53입니다. 그렇죠?
그리고 현재 노드는 +1입니다.
아래의 유도식을 다시 살펴보겠습니다.
(x+상수)에 대한 local gradient는 1입니다. 그렇죠?
이제 chain rule을 이용하면 이 변수에 대한 gradient는 얼마입니까?
upstream gradient는 -0.53이고, 우리의 local gradient는 1입니다. 그렇기 때문에 (gradient 는) -0.53이 됩니다.
한 단계 더 진행해봅시다.
여기에서 우리는 exponential을 가지고 있습니다. upstream gradient는 얼마입니까?
[학생이 마이크로 말하고 있다]
네, upstream gradient는 -0.53이죠.
여기에서 local gradient는 얼마일까요? 이것은 x에 대한 e의 local gradient가 될 것입니다.
exponential 노드에서, chain rule에 의해 gradient가 -0.53*e^x임을 알 수 있습니다.
(x의) 값이 -1인 경우 (exponential 노드에서) 최종 gradient는 -0.2가 됩니다.
좋아요, 노드가 하나 더 있습니다. 다음 노드는 -1과 곱하는 노드입니다. 그렇죠?
여기에서 upstream gradient는 얼마인가요?
[학생] -0.2
네 맞아요, 그리고 local gradient는 무엇이 될까요
유도식을 한번 살펴 보세요.
얼마인가요?
들은것 같네요.
[학생] -1
네 -1 맞아요.
local gradient는 x에 대한 f의 미분입니다. 그러므로 이 노드의 결과는 -1이 됩니다. (1 * -1이 되므로)
그렇기 때문에 gradient는 -1 * -0.2이므로 0.2가 됩니다.
좋아, 이제 우리는 덧셈 노드에 도달했습니다. 그리고 여기에서 우리는 두 개의 노드와 연결됩니다.
일단 여기에서 upstream gradient는 얼마인가요? 그것은 0.2일거에요, 그리고
각 브랜치에 대한 gradient를 추가해봅시다.
이전의 간단한 예제에서 덧셈 노드를 가지고 있을 때 덧셈 노드에서, 각 입력에 대한 local gradient는 1이었습니다.
여기에서 local gradient는 upstream gradient 0.2와 한번 곱해질 것입니다. 맞죠? 1 * 0.2 = 0.2입니다.
그리고 우리는 아래(bottom) 브랜치에 대해서도 똑같이 할 것입니다. 같은 들어오는 gradient 0.2를 이용해서
그리고 총 gradient는 0.2입니다. 여기까지 이해가 되시나요?
좋아요.
몇가지 gradient를 더 채워봅시다. w₀과 x₀이 있는곳까지 가면 여기에서는 곱셈 노드를 가지고 있습니다.
이전에 보았던 곱셈 노드에서 input에 대한 gradient는 한 인풋에 대하여 다른 인풋의 값이었습니다.
이 경우 w₀에 대한 gradient는 얼마일까요?
[학생] -0.2
네 -0.2 맞습니다. w0의 관점에서 upstream gradient 0.2를 가지고 있죠.
아래에 있는 다른 하나(x0)는 -1이기 때문에 -1과 0.2를 곱해 -0.2를 얻게 됩니다.
x0에 대해서도 같은 과정을 반복하면 0.2 * 2를 하게 되므로 0.4를 얻게 됩니다.
모든 gradient를 채워 넣었습니다.
그리고 이전에 질문 중에 왜 이 방식이 특정 변수에 대해서
analytic gradient를 유도해 값을 계산하는 것보다 단순한지가 있었습니다.
우리가 써야만 하는 local gradient에 대한 표현을 여기에서 볼 수 있습니다.
우리가 가진 각각의 값을 결합했습니다.
곱셈으로 나타내기 위해 chain rule을 사용했고 뒤에서부터 시작하여 모든 변수에 대한 gradients를 구했습니다.
그리고 우리는 w0과 x0에 대한 gradient 또한 같은 방법을 사용해 구했습니다.
그리고 주목하기 바라는 것은 우리가 computational graph를 만들 때, computational 노드에 대해 우리가 원하는 세분화된 정의를 할 수 있는 것입니다.
우리는 이번 케이스에서 덧셈과 곱셈, 절대적으로 작은 단위로 쪼갰습니다. 알다시피 덧셈과 곱셈은 더 단순해질 수 없습니다.
실제로 원한다면 이 노드들을 더 복잡한 그룹으로 묶을 수 있습니다.
우리는 그 노드에 대한 local gradient를 적어두기만 하면 됩니다.
예를 들어 sigmoid 함수를 보겠습니다. sigmoid 함수에 대한 정의를 오른쪽 상단에 적어놓았습니다.
이는 1 / (1 + e^-x)와 같습니다. 그리고 이것은 남은 수업에서 많이 보게 될 함수입니다.
그리고 우리는 이것에 대한 gradient를 계산할 수 있습니다. 우리는 이것을 사용할 수 있으며, 분석적으로 이를 살펴본다면
마지막에 좋은 표현을 얻을 수 있습니다.
따라서 이 예제에서 이것은 (1- sigma(x)) * sigma(x)와 같습니다.
그리고 이 경우에 우리는 sigmoid를 만들기 위한 모든 계산을 그래프에 가지고 있습니다.
그리고 우리는 이것을 하나의 big 노드, sigmoid로 바꿀 수 있습니다.
우리는 이 gate의 local gradient, expression 그리고 x에 대한 sigmoid의 미분을 알고 있기 때문이죠. 그렇죠?
여기에서 가장 중요한 사실은 local gradient를 적을 수 있는한 더 복잡한 노드 그룹을 만들 수 있다는 것입니다.
그리고 이 모든것은 trade-off의 관계에 있습니다.
간결하고 단순한 그래프를 얻기 위해 당신이 많은 수학을 알고 싶어하는 것과
각 노드에서 단순한 gradient를 얻고 싶어하는 것 사이에서.
그 결과 당신은 원하는 만큼 복잡한 computational graph를 쓸 수 있습니다.
질문 있나요?
[학생] 이것은 그래프 자체에 대한 질문입니다. 처음의 두 곱셈 노드의 weight들은 덧셈 노드와 연결되어 있지 않습니다. 특별한 이유가 있습니까? (y = wx + b의 느낌으로 질문을 한 듯)
그것들은 하나의 덧셈 노드와 연결되어야 할 것 같은데 질문은 왜 w0와 x0이 w2와 연결이 되어 있지 않냐는 것이죠?
모든 추가 노드들은 서로 연결되어 있기 때문에 제 대답은 당신이 원한다면 그렇게 할 수 있다는 것입니다.
그리고 실제로 당신은 그것을 원할수도 있습니다. 그것은 매우 단순한 노드이기 때문에.
그래서 이 경우 저는 최대한 단순하게 썼습니다.
각 노드는 오직 2개의 입력만 받게, 하지만 당신은 분명 그것을 할 수 있습니다. 이 질문에 대한 다른 질문이 있으십니까?
computational graph로 생각하는 것은 저를 아주 편안하게 만듭니다. gradient를 구할때나 다른 무언가의 gradient를 찾아야만 할 때,
sigmoid 처럼 설사사 그 식이 정말로 복잡하고, 두려워도
우리가 알다시피 필요하다면 이것을 유도해냈습니다. computational graph의 관점에서 나는 적어나갔고
나는 단순하게 진행할 수 있었다. backpropagation과 chain rule을 통해. 그리고 나는 필요한 gradient를 계산할 수 있었다.
그리고 이것은 당신이 과제를 할 때 생각해야 합니다. gradient를 찾기 어려울 때 언제든지 이 방식을 사용해서 알아낼 수 있습니다.
모든 부분들을 쪼개고 chain rule을 적용할 수 있습니다.
아시다시피 우리는 이 노드들을 sigmoid로 그룹화 하는 것을 보았습니다. 실제로 이것이 동등한지 확인했습니다.
우리는 이것을 연결할 수 있습니다. 그러면 우리는 입력이 1 (초록색으로 쓰여 있음) 출력은 0.73을 갖습니다. 그렇죠?
이것은 sigmoid 함수에 연결하면 될 것입니다.
그리고 gradient를 얻기 원한다면 하나의 완전한 sigmoid 노드를 이용할 수 있습니다.
앞에서 이것의 local gradient를 유도했었습니다. 그렇죠?
그것은 (1-sigmoid(x)) * sigmoid(x) 였죠. 즉 이것을 여기에 대입해봅시다.
알고있는 값은 x는 0.73이고 이 값을 위의 식에 대입하면 gradient로 0.2를 얻게 됩니다.
우리는 이것을 upstream gradient인 1과 곱합니다. 그러면 우리는 sigmoid gate로 바꾸기 이전의 작은 노드들로 계산된 값과 정확히 같은 값을 얻을 수 있습니다.
좋아요, 우리가 gradient를 뒤에서부터 가져오는 동안 이제 어떤 일이 일어나는지 봅시다.
직관적 해석으로 알 수 있는 패턴이 있습니다.
덧셈 게이트는 gradient를 나눠줍니다.
두 개의 브랜치와 연결되는 덧셈 게이트에서는 upstream gradient를 연결된 브랜치에 정확히 같은 값으로 나눠줍니다.
여기에는 생각해볼만한 것이 더 있습니다. 그렇다면 max 게이트 모양은 어떤 모양입니까?
아래에 max 게이트가 있습니다. 입력으로 z와 w가 들어오고 z는 2, w는 -1입니다.
그리고 최대값을 취한 다음에 그것을 통과시킵니다.
이것에 대한 gradient를 구해보면, upstream gradient는 2네요 그렇죠.
이 것(max 노드)의 local gradient는 무엇일까요?
[학생] 하나는 0이되고 다른 하나는
맞습니다.
[학생이 마이크로 말하고 있다]
맞습니다. z는 gradient 2를 가질 것이고 w는 gradient 0을 가질 것입니다.
이것은 gradient가 단지 통과하는 효과입니다.
하나는 전체 값이, 다른 하나에는 0의 gradient가 향하게 됩니다.
우리는 이런 종류의 gradient 라우터에 대해 생각할 수 있습니다. 덧셈 노드에서는 같은 gradient를 들어오는 브랜치에게 전달해주기 때문에
max 게이트는 그것을 받고 하나의 브랜치를 지정합니다. 그리고 이것은 forward pass를 볼 때 의미가 있습니다.
값(value)은 무슨일이 일어날까요. 최대값이 남은 computational graph로 통과됩니다.
그래서 결국 함수 계산에 실제로 영향을 주는 값은 유일한 값이므로
따라서 gradient를 다시 전달할 때
무엇을 조정하고 계산의 해당 지점을 통해 흐르게 하는 것이 바람직합니다.
[학생이 마이크로 말하고 있다]
네 답은 local gradient는 기본적으로 다른 변수의 값입니다.
네 정확합니다.
그래서 이것을 gradient switcher라고 생각할 수 있습니다. 맞습니까? Switcher, 저는 scaler라고 추측합니다.
upstream gradient를 받아 다른 브랜치의 값으로 scaling 합니다. 네 그리고 다른 주목할만한 것은 우리가 여러 노드와 연결되어 있는 하나의 노드를 가지고 있을 때
gradient는 이 노드에서 합산됩니다. 맞습니까?
다 변수(multivariate) chain rule을 사용하는 노드들에서 우리는 단지 각 노드들로부터 들어오는 upstream gradient 값을 취하고
그리고 이것들을 합합니다.
그러면 당신은 이것들로부터 다 변수 chain rule을 볼 수 있습니다. 그리고 이것에 대해 생각해보세요,
만약 당신이 이 노드를 조금 변경시킨다면 그래프를 따라 forward pass를 할 때 연결된 노드들에게 영향을 미칠 것입니다.
그리고 당신이 backpropagation을 할 때 이 두개의 gradient가 돌아오면 이 노드에 영향을 미치게 될 것입니다.
따라서 이 값을 더해야 총 upstream gradient가 됩니다.
backpropagation에 대한 질문이 있습니까?
[학생] 우리는 실제 가중치에 대해 아무런 업데이트도 하지 않았습니다.
[마이크로 말하는 중]
네 질문은 우리는 아직 이 가중치 값에 대해서 아무런 업데이트를 하지 않았다는 것입니다.
우리는 변수에 대한 gradient만 찾았습니다. 맞습니다.
이 강의에서 이야기 한 것은 어떻게 함수에서 변수에 대한 gradient를 찾는가였습니다.
찾은 다음 마지막 최적화 강의에서 배운 모든 것을 적용할 수 있습니다.
그래서 gradient가 주어지면, 우리는 가중치를 업데이트하기 위한 다음 스텝을 밟습니다.
당신은 이 모든 구조를 우리가 마지막 최적화강의에서 배운 것에 적용할 수 있습니다.
여기에서 우리가 한 것은 임의의 복잡한 함수에 대해 gradient를 계산하는 것을 배운 것입니다.
따라서 나중에 신경망과 같은 복잡한 함수에 대해 이야기 할 때 유용할 수 있습니다.
[학생] 모든 변이에 대해서 적어 주실 수 있습니까? 이 슬라이드를 이해하는데 도움이 되기 위해
그래요 저는 이것을 보드에 쓸 수 있습니다.
만약 우리가 함수 f의 x에 대한 gradient를 가지고 있으면
변수 i에 의해 연결되어있다고 가정해 보겠습니다.
x는 여러 요소들과 연결되어 있다고 할 수 있습니다.
이 경우에는 ∂qi이고, 그리고 chain rule은 모든것을 취하고 있으며 각각의 중간 변수의 효과를 취할 것입니다.
우리의 최종 출력 f, 그리고 다음 변수 x가 해당 중간 값에 미치는 영향에 대해.
이것은 기본적으로 모든 것들을 합쳐 놓은 것입니다. 좋아요, 이제 우리는 스칼라 값에 대한 모든 예제를 완료했습니다.
이제 벡터가있을 때 어떻게 될까요? 우리의 변수 x,y,z에 대해서 숫자 대신에 vector를 가지고 있다고 합시다.
모든 흐름은 정확히 같습니다. 차이점이라면 우리의 gradient는 Jacobian 행렬이 될 것입니다.
그래서 이것들은 각 요소의 미분을 포함하는 행렬이 될 것입니다. 예를들어 x의 각 원소에 대해 z에 대한 미분을 포함하는.
좋아요, 예제를 하나 봅시다. 우리의 입력은 4096차원의 벡터입니다.
그리고 이것은 CNN에서 흔히 볼 수 있는 사이즈입니다.
그리고 이 노드는 요소별로(elementwise) 최대값을 취합니다.
우리는 f를 가지고 있습니다. 요소별로 0과 비교해 최대 값을 같는 x를 취하는,
그리고 출력 또한 4096 차원의 벡터입니다. 좋아요, 이 경우에 Jacobian 행렬의 사이즈는 얼마인가요?
이전에 말했던 것을 기억해보세요 Jacobian 행렬의 각 행은 입력에 대한 출력의 편미분이 될 것입니다.
제가 들은 답은 4096의 제곱인데요 맞습니다.
그리고 4096*4096은 매우 큽니다.
그리고 실질적으로 이것은 더 커질 수 있습니다.
예로들면 100개의 인풋을 동시에 입력으로 같는 배치를 이용해 작업할 수 있습니다.
그것은 우리의 노드를 더욱 효율적으로 만들지만 그것은 100배 커지게 만듭니다.
실제로 Jacobian은 4096000 * 4096000입니다.
이것은 너무 거대해서 작업에 실용적이지 않습니다.
실제로는, 우리는 이 거대한 Jacobian을 계산할 필요가 없습니다.
그러면 이 Jacobian 행렬이 어떻게 생겨나게 되었을까요?
만약 우리가 요소별로 최대값을 같는 여기에서 어떤 일이 일어나는지 생각해 본다면
우리는 각각의 편미분에 대해 생각해볼 수 있습니다.
입력의 어떤 차원이 출력의 어떤 차원에 영향을 줍니까?
이 Jacobian 행렬에서 어떤 종류의 구조를 볼 수 있습니까?
[학생 대답 중]
네 들었습니다. 대각선, 정확합니다.
이것은 요소별 이기 때문에, 입력의 각 요소, 첫번째 차원은
오직 출력의 해당 요소에만 영향을 줍니다.
그렇기 때문에 우리의 Jacobian 행렬은 대각행렬이 될 것입니다.
실제로 이 전체 Jacobian 행렬을 작성하고 공식화 할 필요는 없습니다.
우리는 출력에 대한 x의 영향에 대해서 그리고 이 값을 사용하는 것에 대해서만 알면 됩니다.
그리고 우리가 계산한 gradient의 값을 채워 넣으면 됩니다.
좋아요, 이제 computational graph보다 구체적인 벡터화 된 예제를 보겠습니다.
보겠습니다. x와 W에 대한 함수 f는
x에 의해 곱해진 W의 L2와 같습니다.
그리고 이 경우 x를 n-차원이라고 하고, W는 n*n이라고 합시다.
네 처음부터 해 봅시다.
computational graph 쓰기.. 맞죠?
우리는 x에 의해 곱해진 W를 가지고 있고
그리고 L2가 뒤따릅니다.
이제 값을 채워 넣읍시다.
W는 2x2 행렬인 것을 볼 수 있고
x는 2차원의 벡터입니다. 맞죠?
우리는 중간 노드를 다시 쓸 수 있습니다.
그것은 q로 할 것이고, W와 x의 곱입니다.
이것은 요소별 방식으로 쓸 수 있습니다.
W1,1 * x1 + W1,2 * x2 등등
그러면 우리는 이제 f를 q에 대한 표현으로 나타낼 수 있습니다. 맞죠?
따라서 q의 두 번째 노드를 보면
이것은 q의 L2 norm과 같습니다.
이것은 q1의 제곱과 q2의 제곱을 합친 것과 같습니다.
네 이것을 채워넣었습니다.
우리는 q를 구했고 최종 출력을 구했습니다.
좋아요, 이제 이것에 대해 backpropagation을 해봅시다.
출력에 대한 gradient를 가지고 있고 이것은 1입니다. 이것은 항상 첫 단계입니다.
이제 한 노드 뒤로 이동합시다.
우리는 L2 이전의 중간 변수인 q에 대한 gradient를 찾기 원합니다.
그리고 q는 2차원의 벡터입니다.
그리고 우리가 진짜 원하는것은 q의 각각의 요소가 f의 최종 값에 어떤 영향을 미치는지 입니다.
그리고아래에 f를 위한 식을 적어놓았습니다.
여기서 우리는 바닥에 f를 위해 를 써 넣었습니다. 우리는 f
qi에 대한 f의 gradient를 볼 수 있습니다.
이것을 q1이라고 부르겠습니다.
이것은 qi * 2가 될 것입니다. 그렇죠?
이것은 도함수를 구하는 것이고, 우리는 이것에 대한 식을 가지고 있습니다.
각각의 요소 qi에 대해서.
우리는 또한 이것을 벡터의 형태로 쓸 수 있습니다.
이것은 우리의 벡터 q에 대해서 2를 곱한 것이었습니다. 그렇죠?
그리고 우리는 이 벡터에서 gradient를 0.44와 0.52를 얻었습니다.
그리고 여러분은 그것이 q를 취해 단순히 2로 곱한것임을 보았습니다.
각 요소는 2로 곱해졌습니다.
벡터의 gradient는 항상 원본 벡터의 사이즈와 같습니다.
그리고 gradient의 각 요소는 의미합니다.
함수의 최종 출력에 얼마나 특별한 영향을 미치는지.
좋아, 그럼 이제 한 걸음 뒤로 이동해봅시다.
W의 gradient는 무엇입니까?
그리고 여기에서 우리는 다시 chain rule을 사용할 것입니다.
우리가 W에 대한 q의 local gradient를 계산하기 원한다면
요소별 연산을 다시 해야할 것입니다.
각각의 q에 대한 영향을 봅시다.
W의 각 요소에 대한 q의 각 요소 그리고 이것은
이전에 말했던 Jacobian일 것입니다.
그리고 우리는 곱셈의 형태로 볼 수 있습니다.
여기에서 q는 W*x와 같습니다.
q의 첫번째 요소의 gradient는 무엇입니까?
도함수 또는 첫 번째 요소의 기울기이므로
W11에 대한 첫 번째 요소가 위로 올라갑니다.
그래서 W11에 대한 q1
그 값은 무엇입니까?
x1, 정확합니다.
우리는 이것이 x1인 것을 알고있죠.
그리고 우리는 이것을 Xj와 동일한 Wi,j에 대한 qk의 식으로 일반화 할 수 있습니다.
그리고 우리는 f에 대한 gradient를 찾기 원합니다. 각 Wij에 대해서
이것들의 도함수를 봅시다.
우리는 chain rule을 사용할 수 있습니다.
여기에서 기본적으로 qk에 대한 f의 미분을 합성 할 때
Wij의 각 요소인 dqk/Wij의 각 요소에 대해합니다. 그렇죠?
그래서 우리는 W의 각 요소들의 영향을 찾을 수 있습니다.
q의 각 요소들에 대해서, 그리고 모든 q에 대해 이것들을 모두 더합니다.
그리고 만약 당신이 이것을 적다보면 이것은 결국 2 * qi * xj와 같은 식을 나타냅니다.
좋아요, 우리가 구한 W에 대한 gradient를 채우면
각 요소들에 대해 다시 계산할 수 있습니다.
또는 우리가 유도한 식을 벡터화된 형식으로 작성할 수 있습니다.
좋아요, 중요한 것은 변수에 대해 gradient를 항상 체크하는 것이에요.
이것들은 항상 변수와 같은 모양(shape)을 가지고 있습니다.
gradient가 무엇인지 계산을 했으면 이것이 변수의 모양과 동일한지 확인하세요. 이것은 검사하는데 있어서 매우 유용합니다.
다시 말해, gradient의 요소는 정량화합니다, 얼마나 최종 출력에 영향을 미치는지를.
응?
[학생이 마이크로 말하는 중]
양쪽 모두 지시 함수(indicator function)입니다. 이것은 k와 i가 같으면 1임을 의미합니다.
좋아요, 봅시다.
이제 또 하나의 예제를 보겠습니다.
이제 우리가 찾아야 할 마지막 것은 qI에 대한 gradient입니다.
dqk/dxi가 Wki와 같은 것을 볼 수 있습니다.
우리가 W에 했던 것과 같은 방식으로
그리고 다시 우리는 체인 규칙을 사용할 수 있습니다.
그리고 그것에 대한 총 표현식을 얻을 수 있습니다. 아시겠습니까? 그리고 이것은 x와 같은 모양을 가진 x에 대한 gradient가 될 것입니다.
또한 이것을 벡터 형식으로 쓸 수 있습니다.
좋아요, 그럼 이것에 대한 질문은 없습니까?
[학생이 마이크로 말하는 중]
우리는 Jacobian을 계산하는 중입니다.
뒤로 한번 돌아가보죠.
계산하는 중에 우리는 xi에 대한 qk의 편도함수를 가지고 있습니다.
그리고 이것들은 Jacobian 행렬을 구성합니다. 맞죠?
그리고 실제로 우리가 할 일은 이것을 가져와서
x에 대한 gradient의 벡터화된 표현으로써 chain rule에서 사용하는 것입니다.
여기에 Jacobian 행렬이 있습니다. 이것은 전치된 값입니다.
당신은 이것을 벡터화된 형식으로 쓸 수 있습니다.
[학생이 마이크로 말하는 중]
이 행렬의 경우 W와 크기와 같습니다. 그리고 이 행렬은 큰 경우는 아닙니다.
그래서 우리가 생각한 방식은 computational graph에서 실제로 모듈화 된 구현과 같습니다.
우리는 각 노드를 local하게 보았고 upstream gradient와 함께 chain rule을 이용해서 local gradient를 계산했습니다.
이것을 forward pass, 그리고 backward pass의 API로 생각할 수 있습니다. forward pass에서는 노드의 출력을 계산하는 함수를 구현하고
backward pass에서는 gradient를 계산합니다.
그래서 우리가 실제로 코드에서 이것을 구현한다면,
우리는 똑같은 방식으로 이 작업을 수행 할 것입니다.
각각의 gate에 대해 생각해 볼 수 있습니다.
forward, backward 함수를 구현할 때 backward 함수는 chain rule을 이용해 계산하고
만약 우리가 완전한 그래프를 가지고 있으면
그래프의 모든 노드를 반복함으로써 전체 그래프를 forward pass로 통과시킬 수 있습니다.
여기에서는 게이트와 노드라는 단어를 사용하려고 합니다. 이 모든 게이트를 반복하여 각 게이트를 호출할 수 있습니다.
그리고 우리는 이것을 위치적으로 정렬 된 순서로 수행하기를 원합니다.
우리는 노드를 처리하기 전에 이 전에 노드로 들어오는 모든 입력을 처리합니다.
그리고 backward로 보면, 역순서로 모든 게이트를 통과한 다음에 게이트 각각을 거꾸로 호출합니다.
좋아요, 그러면 특정 게이트에 대한 구현 살펴보면 여기에 곱셈 게이트가 있습니다.
이것의 forward pass를 구현하려고 합니다.
이것은 x,y를 입력으로 받고 z를 리턴합니다.
그리고 backward로 진행 할 때는 입력으로 upstream gradient인 dz를 받고 출력으로 입력인 x와 y에 gradient를 전달할 것입니다.
그래서 여기서 출력은 dx와 dy입니다.
그리고 이 예제의 경우 모든 것은 scalar 입니다.
그리고 forward pass를 보면 중요한 것은
forward pass의 값을 저장(cache)해야 하는 것입니다. 왜냐하면 이것(forward pass)이 끝나고 backward pass에서 더 많이 사용하기 때문입니다.
그리고 forward pass에서 x와 y도 저장하는데
backward pass에서 chain rule을 사용하여
upstream gradient 값을 이용해 다른 브랜치의 값과 곱합니다.
self.y 와 dz를 곱해 얻은 dx를 보관하게 될 것입니다.
dy에 대해서도 마찬가지입니다.
네 이제 딥러닝 프레임워크 그리고 라이브러리를 보면
그들은 이러한 종류의 모듈화를 따릅니다.
예를들면 Caffe는 유명한 딥러닝 프레임워크입니다.
그리고 당신은 Caffe의 소스 코드를 볼 수 있습니다.
당신은 layer라고 부르는 폴더를 구할 수 있으며
레이어는 기본적으로 computational node이고 보통 레이어는 sigmoid 처럼 당신이 생각하는 것보다 좀 더 복잡합니다.
computational 노드의 전체 목록 볼 수 있습니다. 그렇죠?
당신은 sigmoid를 가질 수 있고 여기에 있을것 같네요,
convolution 같은 것도 여기에 있네요
Argmax도 다른 레이어로 있습니다.
당신은이 모든 레이어들을 가지게 될 것입니다. 만약 당신이 이것들을 탐구하면 정확하게 forward pass, backward pass 등을 구현할 수 있습니다.
이 모든 것들은 호출됩니다.
우리가 만든 전체 네트워크를 통해 forward/backward pass 할 때, 그래서 우리의 네트워크는 기본적으로
우리가 네트워크에 사용하기위해 선택한 레이어들을 쌓게 됩니다.
이 경우 우리는 sigmoid 레이어를 살펴볼 수 있습니다.
우리는 sigmoid 함수에 대해서 이야기 했었습니다.
그것의 forward pass를 볼 수 있습니다.
sigmoid 식과 똑같은 계산을 합니다. 그리고나서 backward pass로 전달합니다.
여기서 upstream gradient인 top_diff를 취합니다.
그리고 우리가 계산한 local gradient와 그것을 곱합니다.
그래서 과제 하나에서는 이런 종류의 연습을 하게 될 것입니다.
computational graph 방식으로 SVM과 Softmax 클래스를 작성하고
이들의 gradient를 구할 수 있습니다.
항상 기억하세요 첫번째 스텝은 computational graph로 나타내는 것입니다.
출력으로 이어지는 모든 계산이 무엇인지 파악한 다음
역방향 계산을 해야할 때
computational graph에서 정의한, 계산에 필요한 중간 변수에 대한 gradient를 가져옵니다.
당신이 계산 그래프에서 정의한
그리고 chain rule을 이용해서 연결합니다.
좋아, 지금까지 얘기 한 내용을 요약해 보겠습니다.
신경망으로 작업 할 때, 이것들은 정말로 크고 복잡 할 것입니다.
그래서 모든 파라미터에 대해 gradient를 손으로 구하고 써내려가는 것은 비현실적입니다. 그래서 gradient를 계산하기 위해서
backpropagation을 사용하는 방법에 대해서 이야기했었습니다.
그리고 이것은 신경망의 핵심 기술이고, gradient를 구하기 위해서 backpropagation을 썼습니다. 그렇죠?
그리고 이것은 우리가 가지고 있는 computational graph에서 chain rule을 재귀적으로 적용한 것입니다.
우리는 뒤에서부터 시작하여 거슬러 올라갔습니다.
입력이나, 파라미터 등등 모든 중간 변수들을 구하기 위해,
그리고 각각의 노드에 대한 그래프 구조의 구현이 실제로 얼마나 큰지 이것들을 forward, backward API 구현으로 나타내는지에 대해서 이야기 했었습니다.
그리고 forward pass에서 우리는 연산 결과를 계산하고 결과를 저장합니다.
그것은 나중에 우리가 gradient를 계산할 때 backward pass에서 chain rule에서 사용하기 위한 것이고
upstream gradient와 저장한 값들을 곱해
각 노드의 input에 대한 gradient를 구합니다. 그리고 우리는 그것들을 연결된 이전 노드로 통과시킵니다.
좋아요, 이제 마지막으로 신경망에 대해서 이야기 해 봅시다. 사람들은 신경망과 뇌 사이에서 많은 유추와 여러 종류의 생물학적 영감을 이끌어냅니다.
우리는 그것에 대해 조금 배우겠지만, 일단 그것에 대해 이야기해봅시다.
우리는 아시다시피 뇌 기능이 없는, 그저 함수 클래스로서 그것들을 보았었습니다.
우리가 지금까지 이야기한것은 우리는 다양한 선형 score 함수를 이용했었습니다. f = W*x, 우리는 이것을
최적화할 때의 실행 예제로 사용했었습니다. 그러면 single 변환을 사용하는 대신에 아주 간단한 형태의 신경망을 사용해봅시다.
위에 있는 것은 선형 변환식이고 다른 하나는 2층짜리 신경망의 레이어입니다. 그렇죠?
이것이 어떻게 생겼나요, 첫번째로 알다시피
W1과 x의 행렬 곱입니다.
그리고 우리는 이것의 중간값을 얻고, 우리가 가진 max(0, W)의 비선형 함수를 이용해
선형 레이어 출력의 max를 얻습니다.
그리고 이 비선형 변환은 매우 중요합니다.
나중에 이것에 대해 더 이야기하겠습니다. 만약 당신이 선형 레이어들을 쌓는다면 그것들은 결국 선형 함수가 될 것입니다.
자 우리는 첫번째 선형 레이어를 같고 있습니다. 그 다음 우리는 비선형 레이어를 가지고 있습니다.
그리고 이것의 위에 선형 레이어를 추가할 것입니다.
여기에서 최종적으로 우리는 score 함수를 얻을 수 있습니다.
그래서 기본적으로 광범위하게 말하면 신경망은 함수들의 집합(class)입니다. 비선형의 복잡한 함수를 만들기 위해서 간단한 함수들을 계층적으로 여러개 쌓아올린.
그리고 이 아이디어는 여러 단계의 계층적 계산으로 이루어져 있습니다. 맞죠?
여러분이 알다시피
이것은 우리가 하는 주된 방법중 하나입니다.
행렬 곱, 중간에 비선형 함수와 함께 선형 레이어를 여러개 쌓아 계산하는 것입니다.
그리고 이것이 이것들을 이해하는데 도움이 되는 한 가지는 이전에 선형 score 함수에 대해서 이야기 했던 것을 생각해보세요
우리의 가중치 행렬 W의 각 행이 각각의 템플릿과 같았는지를 논의했던 것을 기억해보세요.
그것은 일종의 표현된 템플릿이었습니다.
우리가 구체적인 클래스에 대한 입력을 보면
예를들면 자동차 템플릿은 이런 종류의 빨간 차처럼 보입니다.
입력에 대한 car 클래스 스코어를 계산합니다.
우리는 하나의 문제에 대해서만 이야기했습니다. 이것은 오직 하나의 자동차 템플릿만 가지고 있습니다. 그렇죠?
여기에는 빨간 차가 있습니다. 우리는 실제로 여러 모드가 있습니다. 우리는 빨간 차가 있는지 노란 차가 있는지, 다른 여러 종류의 차를 찾기 원할 수도 있습니다.
다중 레이어 네트워크는 그것을 가능하게 합니다.
중간 변수 h와 W1은 이러한 종류의 템플릿일 수 있습니다.
하지만 h에서 이 템플릿들에 대한 모든 점수를 가지고 있습니다. 그리고 우리는 이것을 결합하는 또 다른 레이어를 가질 수 있습니다. 그렇죠?
그래서 실제로 차 클래스가 연결되어야 한다고 말할 수 있습니다. 우리는 빨간 차와 노란 차 모두를 찾기 원하므로.
h의 벡터에 대한 가중치인 W2 행렬을 가지고 있기 때문에
좋아, 이것에 대해 질문이 있으십니까?
그래?
[학생이 마이크로 말하는 중]
네, 많은 방법이 있습니다. 당신이 선택할 수 있는 다른 비선형 함수가 많이 있습니다.
당신이 사용할 수 있는 여러 비선형들에 대해서 추후 강의에 이야기 할 것입니다.
[학생] 슬라이드의 그림에서
[학생] 아래에는 W1 가중치에 대한 그림이 있습니다.
[학생] W2에 대한 그림이있습니까?
W1은 입력과 직접적으로 연결되어 있죠 그래서 이 템플릿을 공식화 할 수 있기 때문에 해석가능한 것입니다.
W2는 h의 스코어가 될 것입니다.
얼마나 많은 점수를 얻었는지를 알 수 있습니다. W2는 당신이 가지고 있는 것처럼 나올 것입니다. 나는 그것을 예측할 수 없습니다.
[학생] W1이 10인 경우 말고, 만약 오른쪽을 향하고 있는 말과 왼쪽을 향하고 있는 말을 동시에 표현할 수 있습니까?
네, 정확히 말하자면 W1이 왼쪽으로 향해있는 말과
오른쪽으로 향해있는 말을 모두 가질 수 있는지인데요, 그렇습니다. W1은 많은 다른 종류의 템플릿이 될 수 있습니까?
안됩니다. 그리고 W2는 모든 템플릿의 가중치를 합한 것입니다.
그것은 특정 클래스에 대한 최종 스코어를 얻기 위해
여러 템플릿의 가중치를 합할 수 있게 해줍니다.
[학생] 만약 실제로 왼쪽으로 향하고 있는 말의 이미지를 이용해 작업을 하면 왼쪽을 향하는 말의 템플릿에서 높은 점수를 얻고
[학생] 오른쪽을 향하고 있는 말에서는 낮은 점수를 얻겠죠
[학생]그러면 이것의 최대값을 구합니까?
질문은 만약 우리의 이미지 x가 왼쪽을 향하고 있는 말이고 그리고 W1이 왼쪽을 향하고 있는 말의 템플릿과
오른쪽을 향하고 있는 말의 템플릿을 가질 때, 이때 어떤일이 일어나는지에 대해서였습니다.
무슨일이 일어날까요?
h에서 왼쪽을 향하고 있는 말은 점수가 높게 나올 것이고,
오른쪽을 향하고 말에 대해서는 낮은 점수를 얻을 것입니다.
그리고 W2는 가중치들의 합입니다. 따라서 최대값이 아닙니다. 이것은 템플릿들의 가중치의 합계입니다.
하지만 이 템플릿중 하나에 대해서 정말로 높은 점수를 얻었거나 두 템플릿 모두에 대해서 낮거나 중간의 점수를 얻었다고 해봅시다.
이것들의 조합은 둘다 높은 점수를 얻을 것입니다. 그렇죠?
결국 당신이 얻고 싶은 것은 특정한 종류의 말을 가지고 있을 때
일반적으로 높은 점수를 얻는 것입니다. 어떤 종류의 말이라도 가지고 있을 때, 앞을 보고 있는 말을 가지고 있다고 해봅시다.
당신은 아마 왼쪽, 오른쪽을 보는 말의 템플릿에 대해서 두개 다 중간정도의 점수를 가질 것입니다.
질문있나요?
[학생] W2가 가중치를 쓰고 있습니까? 아니면 H가 가중치를 쓰고 있습니까?
W2가 가중치를 쓰고 있습니다. 질문은 즉 "W-two가 가중치를 부여합니까, 아니면 h가 가중치를 부여하고 있습니까?" 이거죠? h는 값입니다.
h는 W1에서 가지고 있는 템플릿에 대한 스코어 값입니다.
그래서 h는 스코어 함수입니다. 아시겠습니까?
그것은 W1의 각 템플릿이 얼마나 많은지를 나타내주는 것이고
W2는 이들 모두에 가중치를 부여하고 모든 중간 점수를 더해 클래스에 대한 최종 점수를 얻습니다.
[학생] 그것은 비선형입니까?
비선형이냐는 질문이 있었는데요 h 이전에 비선형성이 발생하므로
h는 비선형 값입니다. 우리는 이것에 대해 이야기하고 있습니다.
이 예제에서 직관적으로 W1은 같은 템플릿을 찾는 것이고
그리고 W2는 이것들에 대한 가중치입니다.
실제로는 정확히 이렇지는 않습니다. 왜냐하면 말했던 것처럼 비선형적인 것들이 나오기 때문입니다.
이것들은 대략적인 해석을 가지고 있습니다.
[학생] h는 W1*X 인가요?
네네, 질문은 h는 W1*X인가 였는데요
h는 딱 W1과 X의 곱입니다. max function을 위에 두고 있는.
우리는 이 두 레이어로 구성된 신경망에 대해서 이야기 했습니다.
그리고 우리는 더 많은 레이어를 쌓아 임의의 깊은 신경망을 구성할 수 있습니다.
우리는 이것을 한번 더 곱해봅시다.
다른 비선형 행렬 W3로 곱할 수 있습니다. 이제 우리는 3-레이어 신경망을 가지고 있습니다. 그렇죠? 이런것으로부터 깊은 신경망이라는 용어가 나오게 됩니다.
복잡한 네트워크의 경우 이러한 계층을 여러 개 쌓는 아이디어에서 나옵니다.
과제를 하다보면 쓰기(writing) 연습을 하게 될 것입니다.
신경망 중 하나를 학습하다보면, 과제 2에서
기본적으로 forward pass, backward pass를 완벽하게 구현하게 됩니다.
gradient를 구하기 위해 앞서 보았던 chain rule을 사용하게 됩니다. 2-레이어 네트워크의 전체 구현은 실제로 매우 단순합니다.
이것은 20줄로 할 수 있습니다.
그리고 당신은 이 과제 2에서 이 파트들을 쓰는 연습을 하게 될 것입니다.
우리는 신경망이 무엇인지를 함수로써 살펴보았습니다.
알다시피, 우리는 신경망에 대한 생물학적 영감에 대해
많은 이야기를 하는것을 듣게 됩니다.
이것을 강조하는것은 중요합니다.
비록 분석이 실제로 loose 하지만
이것은 정말로 loose한 관계입니다. 하지만 이러한 연결과 영감이 어디에서 왔는지 이해하는데 있어 여전히 흥미롭습니다.
이것에 대해서 간략하게 이야기해봅시다.
뉴런에 대해서 생각해보면 그것은 단순합니다.
이것은 뉴런의 다이어그램입니다.
우리는 각 뉴런을 따라 전달되는 신호를 가지고 있습니다. 그리고 우리는 서로 연결된 많은 뉴런을 가지고 있습니다. 그리고 각 뉴런은 수상돌기를 가지고 있습니다.
그것들은 뉴런에 들어온 신호를 받습니다.
그리고 우리는 세포체(cell body)를 가지고 있습니다.
이것은 기본적으로 들어오는 신호를 종합합니다.
이것들을 받아 합친 후에 모든 신호는
하류 뉴런과 연결된 다른 세포체로 이동합니다.
이것은 축삭(axon)을 통해 운반됩니다.
지금까지 우리가 해왔던 것을 보았을 때 각 computational node는 실제 동작과 비슷한 방식으로 볼 수 있습니다.
노드가 computational graph에서 서로 연결되어 있고
입력 또는 신호는 x입니다. 뉴런에 들어가는 것처럼
모든 x0, x1, x2, 모든 x는
우리의 가중치 W와 결합되어 합쳐집니다.
우리는 일종의 계산을합니다. 우리가 해왔던 일부 계산에서는 W를 x와 곱하고 b를 더했습니다.
모든것을 통합하였고 그리고 활성 함수를 꼭대기에 적용했습니다.
출력 값을 얻었고
아래로 연결된 뉴런에 전달했습니다.
이것을 보면 당신은 매우 비슷한 방식이라고 생각할 수 있습니다. 그렇죠?
알다시피 이것들은 들어오는 신호가 시냅스에서 연결되는 것들입니다. 그렇죠?
여러개의 뉴런과 연결된 시냅스, 그리고 수상돌기는
세포체로 이 모든 정보를 합칩니다.
그리고 나서 우리는 출력을 실었습니다.
이것은 표현할 수 있는 일종의 비유입니다.
그리고 당신은 이 활성함수를 볼 수 있습니다. 그렇죠?
이것은 입력을 받아 나중에 출력이 될 하나의 숫자를 보여주는 것입니다.
우리는 sigmoid 및 여러 종류의 비선형과 관련해서 이야기 했습니다.
그리고 이것은 loose한 종류입니다.
당신은 비선형성으로 뉴런의 firing이나 spiking에 대해서 표현할 수 있습니다.
우리의 뉴런이 이산 spike 종류를 사용해서 신호를 전송합니다. 그렇죠?
알다시피 생각해볼 수 있습니다.
그것들이 매우 빠르게 spiking 하는 경우 전달되는 강한 신호가 있습니다. 그래서 우리는 활성함수를 통과한 다음에 이 값을 생각할 수 있습니다.
알다시피 실제로, 이것을 연구하고 있는 신경 과학자들은
실제 방식과 가장 유사한 비선형성의 종류가
ReLU라고 말합니다.
나중에 더 자세히 볼꺼지만 이것은 함수입니다.
모든 음수 입력값에 대해서 0이고, 양수 입력에 대해서는 선형 함수인.
알다시피 우리는 활성함수에대해 나중에 더 이야기 할 것입니다.
실제로 이것들은 뉴런들의 행동과 비슷하지만,
실제 생물학적 뉴런은 이보다 훨씬 복잡하기 때문에
이러한 종류의 신경을 만드는 것은 매우 신중해야 합니다.
생물학적 뉴런에는 여러 종류가 있습니다. 수상돌기는 실제로 복잡한 비선형 계산을 수행할 수 있습니다.
우리의 시냅스, 이전에 비유적으로 그렸던 W0은
우리가 가진 것처럼 단일 가중치가 아니며, 실제로 엄청 복잡한 비선형 시스템입니다.
우리의 활성함수를 일종의 rate code나 fire rate로 해석하는
이러한 아이디어는 실제로는 불충분합니다.
이러한 종류의 firing rate는 충분한 모델이 아닐 것입니다.
뉴런이 어떻게 하부의 뉴런과 통신하는지에 대해서.
아주 간단한 방법처럼 뉴런은 가변 fire rate로 발사할 것이고,
이 가변성에 대해서 고려되어야 할 것입니다.
우리가 다루는 것보다 훨씬 복잡한 모든 것이 있습니다.
수상돌기의 계산에 예제에 관한 레퍼런스가 있습니다.
이 주제에 관심이 있다면 살펴볼 수 잇습니다.
하지만 실제로 알다시피, 우리는 높은 수준에서 많은 뉴런을 닮은 것들을 볼 수 있습니다.
하지만 실제로 그것들은 더 복잡합니다.
우리는 사용될 수 있는 많은 다른 종류의 활성함수에 대해서 이야기 했습니다.
거기에는 앞서 언급한 ReLu도 있었습니다. 그리고 당신이 사용하고 싶어할 수 있는 다른 종류의 활성함수에 대해서
나중에 자세히 다룰 것입니다.
그리고 우리는 다른 종류의 신경망에 대해서도 이야기 할 것입니다.
우리는 완전히 연결된 신경망 예제를 보았습니다.
각 레이어는 행렬곱을 했고,
우리가 2-레이어 신경망이라고 불렀던 것은
우리가 선형 레이어를 2개 가지고 있다는 사실에 입각했었습니다.
그것은 행렬 곱셈을 하는 완전히 연결된 두 층입니다.
이것을 하나의 히든 레이어 네트워크로 부를 수 있습니다. 행렬 곱의 수를 세는 대신에 히든 레이어를 셀 수 있습니다.
제 생각에는 두 가지 중 하나를 사용할 수 있습니다.
아마 2-레이어 신경망이 조금 더 일반적으로 사용될 것 같습니다. 또한 여기에서 우리의 3-레이어 신경망은
2-히든 레이어 신경망으로 부를 수 있습니다.
feed forward를 할 때 우리는 보았습니다.
네트워크 안의 각 노드에 forward pass를 수행하는 것은
이전에 보여주었던 뉴런의 행동과 같습니다. 맞나요?
그리고 실제 동작에서 생각해볼 수 있는 것은 기본적으로 각 히든 레이어는 완전한 벡터인 것입니다.
이러한 행렬 곱셈을 통해
우리의 뉴런 값을 계산하는 방식으로 쓰면
우리는 뉴런의 전체 레이어를 효율적으로 평가할 수 있습니다.
따라서 하나의 행렬 곱셈을 사용하면 10,50 또는 100개의 뉴런을 의미하는 레이어의 출력값을 얻을 수 있습니다.
좋아요, 그리고 다시 살펴보면
우리가 가지고 있는 벡터 행렬 형태의 출력은 비선형성을 가집니다.
여기에서 사용한 F는 sigmoid 함수입니다.
그리고 우리의 데이터는 x로 받습니다.
첫 번째 행렬 곱 W1은 가장 윗줄에 있습니다.
비선형성을 적용한 다음, 두 번째 히든 레이어 h2를 얻기 위한 두 번째 행렬곱을 합니다.
그리고 최종 출력을 얻습니다. 아시겠습니까?
그리고 아시다시피 앞에서 보았던 backward pass는 신경망을 쓰기(write) 위해 기본적으로 필요할 것입니다.
그리고 모든 것을 계산하기 위해 backpropagation을 쓰기만 하면 됩니다.
그리고 신경망이 무엇인지에 대한 주요 아이디어가 있습니다. 요약하자면, 어떻게 뉴런을 선형 레이어와 fully-connected로 재배열하는지에 대해서 이야기했습니다.
이 레이어의 추상화는 이 모든 것을 계산하는데 매우 효율적인
벡터화된 코드를 사용할 수 있게 하는 좋은 속성을 가지고 있습니다. 우리는 또한신경망이 생물학적 비유와 loose한 영감을 가지고 있음을
명심하는 것이 얼마나 중요한지에 대해 이야기 했습니다. 하지만 실제로는 신경이 아닙니다.
제 말은 즉 우리가 만들고 있는 것은 꽤나 loose한 유추라는 것입니다.